{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "initial_id",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    ""
   ]
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 1  定义工具",
   "id": "8aa746f6add23c6c"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T06:52:34.251923Z",
     "start_time": "2025-09-11T06:52:31.371683Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import os\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "\n",
    "# 定义 AVILY_KEY 密钥\n",
    "os.environ[\"TAVILY_API_KEY\"] = \"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\"\n",
    "# 查询 Tavily 搜索 API\n",
    "search = TavilySearchResults(max_results=1)\n",
    "# 执行查询\n",
    "res = search.invoke(\"今天上海天气怎么样\")\n",
    "print(res)"
   ],
   "id": "d6994c01769e34e1",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'title': '中国气象局-天气预报-城市预报- 上海', 'url': 'https://weather.cma.cn/web/weather/58367.html', 'content': '时间 08:00 11:00 14:00 17:00 20:00 23:00 02:00 05:00\\n天气Image 24Image 25Image 26Image 27Image 28Image 29Image 30Image 31\\n气温 28℃29.4℃30.6℃28.8℃28.2℃26.9℃26.5℃25.8℃\\n降水 0.5mm 1.1mm 3.7mm 1.3mm 无降水 无降水 无降水 无降水\\n风速 3.3m/s 3.3m/s 3.2m/s 3.1m/s 2.8m/s 2.8m/s 3m/s 3m/s\\n风向 东北风 东北风 东北风 东北风 东北风 东北风 东北风 东北风\\n气压 1012.1hPa 1012.3hPa 1011.4hPa 1011.6hPa 1012.8hPa 1013hPa 1012.2hPa 1012.6hPa\\n湿度 89.2%75.6%80.5%81.3%84%84.3%83.6%83.4%\\n云量 65%70%70%70%6.1%80%80%80% [...] 时间 08:00 11:00 14:00 17:00 20:00 23:00 02:00 05:00\\n天气Image 48Image 49Image 50Image 51Image 52Image 53Image 54Image 55\\n气温 31.4℃32.4℃31.7℃30.1℃28.2℃27.2℃27℃26.2℃\\n降水 0.1mm 0.1mm 无降水 无降水 无降水 0.1mm 5.2mm 无降水\\n风速 7.9m/s 7.9m/s 7.8m/s 7.5m/s 7.5m/s 3m/s 3.1m/s 3m/s\\n风向 西北风 西北风 西北风 西北风 东北风 东北风 东南风 东南风\\n气压 1011.2hPa 1011.7hPa 1010.7hPa 1010.9hPa 1012.2hPa 1011.8hPa 1011.4hPa 1011.6hPa\\n湿度 87%69.6%76.2%77.3%82.9%88.5%90.4%93.2%\\n云量 85.6%74.5%31.5%54.9%29.6%65%70%9.3% [...] 时间 17:00 20:00 23:00 02:00 05:00 08:00 11:00 14:00\\n天气Image 16Image 17Image 18Image 19Image 20Image 21Image 22Image 23\\n气温 27.6℃27.1℃26.8℃26℃26.5℃28℃29.4℃30.6℃\\n降水 17.4mm 3.2mm 1.7mm 0.5mm 无降水 0.5mm 1.1mm 3.7mm\\n风速 3m/s 2.9m/s 3m/s 3.1m/s 3.1m/s 3.3m/s 3.3m/s 3.2m/s\\n风向 东北风 西北风 西北风 西北风 东北风 东北风 东北风 东北风\\n气压 1010.5hPa 1010.9hPa 1011.3hPa 1010.4hPa 1010.9hPa 1012.1hPa 1012.3hPa 1011.4hPa\\n湿度 88.7%87.3%98.1%92.7%91%89.2%75.6%80.5%\\n云量 88.1%99.9%86%65%45.5%65%70%70%', 'score': 0.7325349}]\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 2 定义Retriever",
   "id": "3ce7eee7ddda76b9"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T06:54:51.799642Z",
     "start_time": "2025-09-11T06:54:38.946996Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "import os\n",
    "import dotenv\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "# 1. 提供一个大模型\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY1\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "embedding_model = OpenAIEmbeddings()\n",
    "\n",
    "# 2.加载HTML内容为一个文档对象\n",
    "loader = WebBaseLoader(\"https://zh.wikipedia.org/wiki/%E7%8C%AB\")\n",
    "docs = loader.load()\n",
    "#print(docs)\n",
    "\n",
    "# 3.分割文档\n",
    "splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=1000,\n",
    "    chunk_overlap=200\n",
    ")\n",
    "\n",
    "documents = splitter.split_documents(docs)\n",
    "\n",
    "# 4.向量化 得到向量数据库对象\n",
    "vector = FAISS.from_documents(documents, embedding_model)\n",
    "\n",
    "# 5.创建检索器\n",
    "retriever = vector.as_retriever()\n",
    "\n",
    "# 测试检索结果\n",
    "# print(retriever.invoke(\"猫的特征\")[0])"
   ],
   "id": "cddec75c79c69d8b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "page_content='感官[编辑]\n",
      "貓的感官適於狩獵。在哺乳類動物中，貓的聽覺、視覺、嗅覺、味覺、觸覺極敏銳。\n",
      "\n",
      "視覺[编辑]\n",
      "貓的瞳孔能縮得如線般狹小\n",
      "貓的瞳孔變化\n",
      "貓在晝間視覺縱不及人類，夜視能力與追蹤視覺上之活動物件卻相當出色，夜視能力是人類的六倍，雖然綜合色彩計算整體視覺系數則僅及人類的十分之一。貓的眼睛具有微光觀察能力，即使只有微弱月光都可分辨物件，有關光線入貓眼後可放大40至50倍處理，令貓具有夜間活動的能力，即使在黑暗的地下室貓咪依然能活動自如。強光下，貓會將瞳孔縮得如線般狹小，以減少對視網膜的傷害，但視野會因而縮窄。由於貓眼具備高幀與高分辨率視覺，故此電視機極微細之動靜對貓而言亦成逐格跳躍之畫面。[51]\n",
      "另外，不只是光線會影響貓的瞳孔，感情也會。一般而言貓放鬆的時候瞳孔會縮小，而緊張時會放大。\n",
      "貓的視網膜背面有一層藍綠色如熒光一般的薄膜（Tapetum Lucidum），可增加在暗處的視力。閃光中，貓眼能呈現各式各樣顔色。如同多數食肉動物，貓眼長在臉上朝正前方，賦予其遼闊的視野，單一貓眼視野為100度，雙眼視野為285度，加上頸旋靈活，總計視野比人類雙眼僅100度靈活得多。不過，貓僅能聚焦其前30厘米至3米之物件，相對人類而言屬大近視。\n",
      "貓對三原色的辨識力很差，相對人類而言，貓有黃藍色盲且紅綠色辨成灰黃色，與狗相似。關於貓的夜視能力，生物學家發現牛磺酸對貓的視力起了很大作用，貓本身不能合成牛磺酸，必須由外攝取。缺乏牛磺酸，會使視力及夜視能力變差，影響夜間活動。據生物學家稱，貓經常捕鼠，是因老鼠體內含牛磺酸。[52][53]\n",
      "紫外線可以通過貓的晶状体。\n",
      "當四周光線微弱，貓會用感覺毛來改善行動力與感知能力。感覺毛主要分布於鼻子兩側、下巴、雙眼上方、兩頰也有數根。感覺毛可感受非常微弱的空氣波動，視野不清時也能協助辨識阻礙位置。鬍鬚尖端與雙耳連成一線，恰是身體能通過障礙的最小範圍，故貓可在黑夜中快速判斷地形能否通過。\n",
      "貓有第三眼瞼，當貓眼睑張開時，眨眼時第三眼瞼會從旁稍微遮蓋眼睛。若貓生病，或是睡眠，笑著，此眼皮會縮回一部分。若貓長時間嶄露第三眼瞼，表示它的健康有問題。' metadata={'source': 'https://zh.wikipedia.org/wiki/%E7%8C%AB', 'title': '猫 - 维基百科，自由的百科全书', 'language': 'zh'}\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 3 创建工具、工具集",
   "id": "3a34bf6648829317"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T06:55:57.100929Z",
     "start_time": "2025-09-11T06:55:57.086328Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.tools.retriever import create_retriever_tool\n",
    "\n",
    "# 创建一个工具来检索文档\n",
    "retriever_tool = create_retriever_tool(\n",
    "    retriever=retriever,\n",
    "    name=\"wiki_search\",\n",
    "    description=\"搜索维基百科\",\n",
    ")\n",
    "\n",
    "# 构建工具集\n",
    "tools = [search, retriever_tool]"
   ],
   "id": "60873e25361aee45",
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 4 语言模型调用工具",
   "id": "cd363c7ebb8b6e10"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T06:56:46.163938Z",
     "start_time": "2025-09-11T06:56:42.563574Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.messages import HumanMessage\n",
    "\n",
    "# 获取大模型\n",
    "model = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "# 模型绑定工具\n",
    "model_with_tools = model.bind_tools(tools)\n",
    "\n",
    "# 根据输入自动调用工具\n",
    "messages = [HumanMessage(content=\"今天上海天气怎么样\")]\n",
    "response = model_with_tools.invoke(messages)\n",
    "print(f\"ContentString: {response.content}\")\n",
    "print(f\"ToolCalls: {response.tool_calls}\")\n"
   ],
   "id": "32e1dede3304cf04",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ContentString: \n",
      "ToolCalls: [{'name': 'tavily_search_results_json', 'args': {'query': '今天上海天气'}, 'id': 'call_0ZwhabhDrd4N41HeRvzNCVW1', 'type': 'tool_call'}]\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 5 创建Agent程序(使用通用方式)",
   "id": "7ca438a6ef59e692"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T06:58:24.316499Z",
     "start_time": "2025-09-11T06:58:23.641586Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain import hub\n",
    "prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
    "\n",
    "print(prompt.messages)"
   ],
   "id": "7d85000d05554b62",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\developTools\\miniconda3\\envs\\pyth310\\lib\\site-packages\\langsmith\\client.py:272: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='You are a helpful assistant'), additional_kwargs={}), MessagesPlaceholder(variable_name='chat_history', optional=True), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={}), MessagesPlaceholder(variable_name='agent_scratchpad')]\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T06:59:20.339146Z",
     "start_time": "2025-09-11T06:59:20.038854Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.agents import create_tool_calling_agent\n",
    "from langchain.agents import AgentExecutor\n",
    "\n",
    "# 创建Agent对象\n",
    "agent = create_tool_calling_agent(model, tools, prompt)\n",
    "\n",
    "# 创建AgentExecutor对象\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools,verbose=True)"
   ],
   "id": "1fd34dea5a076186",
   "outputs": [],
   "execution_count": 8
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 6 运行Agent",
   "id": "1e5be2c411559d8a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T07:00:01.710864Z",
     "start_time": "2025-09-11T06:59:53.349096Z"
    }
   },
   "cell_type": "code",
   "source": "print(agent_executor.invoke({\"input\": \"猫的特征\"}))",
   "id": "1e24cf168af0c795",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m\n",
      "Invoking: `wiki_search` with `{'query': '猫的特征'}`\n",
      "\n",
      "\n",
      "\u001B[0m\u001B[33;1m\u001B[1;3m感官[编辑]\n",
      "貓的感官適於狩獵。在哺乳類動物中，貓的聽覺、視覺、嗅覺、味覺、觸覺極敏銳。\n",
      "\n",
      "視覺[编辑]\n",
      "貓的瞳孔能縮得如線般狹小\n",
      "貓的瞳孔變化\n",
      "貓在晝間視覺縱不及人類，夜視能力與追蹤視覺上之活動物件卻相當出色，夜視能力是人類的六倍，雖然綜合色彩計算整體視覺系數則僅及人類的十分之一。貓的眼睛具有微光觀察能力，即使只有微弱月光都可分辨物件，有關光線入貓眼後可放大40至50倍處理，令貓具有夜間活動的能力，即使在黑暗的地下室貓咪依然能活動自如。強光下，貓會將瞳孔縮得如線般狹小，以減少對視網膜的傷害，但視野會因而縮窄。由於貓眼具備高幀與高分辨率視覺，故此電視機極微細之動靜對貓而言亦成逐格跳躍之畫面。[51]\n",
      "另外，不只是光線會影響貓的瞳孔，感情也會。一般而言貓放鬆的時候瞳孔會縮小，而緊張時會放大。\n",
      "貓的視網膜背面有一層藍綠色如熒光一般的薄膜（Tapetum Lucidum），可增加在暗處的視力。閃光中，貓眼能呈現各式各樣顔色。如同多數食肉動物，貓眼長在臉上朝正前方，賦予其遼闊的視野，單一貓眼視野為100度，雙眼視野為285度，加上頸旋靈活，總計視野比人類雙眼僅100度靈活得多。不過，貓僅能聚焦其前30厘米至3米之物件，相對人類而言屬大近視。\n",
      "貓對三原色的辨識力很差，相對人類而言，貓有黃藍色盲且紅綠色辨成灰黃色，與狗相似。關於貓的夜視能力，生物學家發現牛磺酸對貓的視力起了很大作用，貓本身不能合成牛磺酸，必須由外攝取。缺乏牛磺酸，會使視力及夜視能力變差，影響夜間活動。據生物學家稱，貓經常捕鼠，是因老鼠體內含牛磺酸。[52][53]\n",
      "紫外線可以通過貓的晶状体。\n",
      "當四周光線微弱，貓會用感覺毛來改善行動力與感知能力。感覺毛主要分布於鼻子兩側、下巴、雙眼上方、兩頰也有數根。感覺毛可感受非常微弱的空氣波動，視野不清時也能協助辨識阻礙位置。鬍鬚尖端與雙耳連成一線，恰是身體能通過障礙的最小範圍，故貓可在黑夜中快速判斷地形能否通過。\n",
      "貓有第三眼瞼，當貓眼睑張開時，眨眼時第三眼瞼會從旁稍微遮蓋眼睛。若貓生病，或是睡眠，笑著，此眼皮會縮回一部分。若貓長時間嶄露第三眼瞼，表示它的健康有問題。\n",
      "\n",
      "貓爪[编辑]\n",
      "貓的爪子尖銳還能有伸縮作用，能夠向外露張開或是往內縮閉藏起來。貓的趾底有脂肪肉墊，因而行走無聲。而按一下這個肉墊，尖銳的勾爪就會伸出來，養貓的人一般使用這種方法來剪爪。大部分貓都有磨爪的習慣。而貓喜好的磨爪物各不相同。家貓可能會選擇沙發、牆壁甚至人類的衣物等作為自己的磨爪物。\n",
      "\n",
      "感官[编辑]\n",
      "貓的感官適於狩獵。在哺乳類動物中，貓的聽覺、視覺、嗅覺、味覺、觸覺極敏銳。\n",
      "\n",
      "^ 生物學特性和解剖生理特點-醫生在線[永久失效連結]\n",
      "\n",
      "^ 51.0 51.1 51.2 《寵藝透視》. 寵藝透視. 2013-07: 50. \n",
      "\n",
      "^ 貓為什麼要吃老鼠？德國生物學家解開謎團. china.ibtimes.com. [永久失效連結]\n",
      "\n",
      "^ 美國藝術家模擬貓的視覺　記錄貓眼看到的世界景像.   [2014-04-05]. （原始内容存档于2014-04-07）. \n",
      "\n",
      "^ At Home : Care / Health : Understanding Cats.   [2005-08-15]. （原始内容存档于2008-02-01）. \n",
      "\n",
      "^ Strain, G.M., How Well Do Dogs and Other Animals Hear?.   [2007-05-12]. （原始内容存档于2011-08-28）. \n",
      "\n",
      "^ The Nose Knows. About.com.   [2006-11-29]. （原始内容存档于2010-12-06）. \n",
      "\n",
      "^ Li, Xia; Weihua Li, Hong Wang, Jie Cao, Kenji Maehashi, Liquan Huang, Alexander A. Bachmanov, Danielle R. Reed, Véronique Legrand-Defretin, Gary K. Beauchamp, Joseph G. Brand. Pseudogenization of a Sweet-Receptor Gene Accounts for Cats' Indifference toward Sugar. PLOS Genetics (Public Library of Science). 2005-07-25, 1 (1)  [2006-11-08]. doi:10.1371/journal.pgen.0010003. （原始内容存档于2021-03-13）.  引文使用过时参数coauthors (帮助)\n",
      "\n",
      "^ 胡苓芝、李冠群. 三花猫-花色形成的原因(下)（Calico Cat）. 科學Online. 2009-04-27  [2015-02-19]. （原始内容存档于2015-02-19）.\n",
      "\n",
      "聽覺[编辑]\n",
      "貓每隻耳各有32條獨立的肌肉控制耳殼轉動，因此雙耳可單獨朝向不同的音源轉動，使其向獵物移動時仍能對周遭其他音源保持直接接觸。[54]除了蘇格蘭折耳貓這類基因突變的貓以外，貓極少有狗常見的「垂耳」，多數的貓耳向上直立。當貓忿怒或受驚時，耳朵會貼向後方，並發出咆哮與「嘶」聲。\n",
      "貓與人類對低頻聲音靈敏度相若。人類中只有極少數的調音師能聽到20 kHz以上的高頻聲音（8.4度的八度音），貓則可達64kHz（10度的八度音），比人類要高1.6個八度音，甚至比狗要高1個八度；但是貓辨別音差須開最少5度，比起人類辨別音差須開最少0.5度來得粗疏。[51][55]\n",
      "\n",
      "嗅覺[编辑]\n",
      "家貓的嗅覺較人類靈敏14倍[56]。貓的鼻腔內有2億個嗅覺受器，數量甚至超過某些品種的狗（狗嗅覺細胞約1.25億～2.2億）。\n",
      "\n",
      "味覺[编辑]\n",
      "貓早期演化時由於基因突變，失去了甜的味覺，[57]但貓不光能感知酸、苦、鹹味，选择适合自己口味的食物，还能尝出水的味道，这一点是其他动物所不及的。不过总括来说猫的味觉不算完善，相比一般人類平均有9000個味蕾，貓一般平均僅有473個味蕾且不喜好低於室溫之食物。故此，貓辨認食物乃憑嗅覺多於味覺。[51]\n",
      "\n",
      "觸覺[编辑]\n",
      "貓在磨蹭時身上會散發出特別的費洛蒙，當這些獨有的費洛蒙留下時，目的就是在宣誓主權，提醒其它貓這是我的，其實這種行為算是一種標記地盤的象徵，會讓牠們有感到安心及安全感。\u001B[0m\u001B[32;1m\u001B[1;3m猫的特征主要体现在其感官、身体构造以及行为习性等方面。以下是一些主要特征：\n",
      "\n",
      "1. **感官能力**：\n",
      "   - **视力**：猫的夜视能力非常优秀，能够在微弱的光照下活动。它们的眼睛具有特殊的闪光膜，能提升在暗处的视力。猫的视野约为285度，比人类更广，但它们的聚焦能力有限，一般只能看清前方30厘米到3米的物体。\n",
      "   - **听力**：猫的耳朵具有32条独立的肌肉，可以独立转动，能够精准定位声音来源。它们能够感知的高频声音高达64kHz，优于人类。\n",
      "   - **嗅觉**：猫的嗅觉比人类敏锐约14倍，鼻腔内有大约2亿个嗅觉受器，是捕猎的关键能力。\n",
      "   - **味觉**：猫的味觉比较有限，失去了对甜味的感知，但是对酸、苦和咸味仍然敏感。\n",
      "\n",
      "2. **爪子**：猫的爪子非常尖锐，并且具有伸缩功能，能够安静地行走。它们的趾底有脂肪垫，走路时不发出声音。\n",
      "\n",
      "3. **身体构造**：猫灵活的身体结构使它们能够轻松地跳跃和攀爬。它们的感官毛（触须）可以感知非常微弱的空气波动，帮助它们判断周围环境。\n",
      "\n",
      "4. **行为习性**：猫有磨爪的习惯，常用爪子磨擦物体以维持爪子的健康。此外，猫会用气味标记地盘，通过脸部和身体上的腺体分泌的特殊费洛蒙进行社交互动。\n",
      "\n",
      "这些特征使得猫在自然界中成为有效的捕猎者和适应环境的生物。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '猫的特征', 'output': '猫的特征主要体现在其感官、身体构造以及行为习性等方面。以下是一些主要特征：\\n\\n1. **感官能力**：\\n   - **视力**：猫的夜视能力非常优秀，能够在微弱的光照下活动。它们的眼睛具有特殊的闪光膜，能提升在暗处的视力。猫的视野约为285度，比人类更广，但它们的聚焦能力有限，一般只能看清前方30厘米到3米的物体。\\n   - **听力**：猫的耳朵具有32条独立的肌肉，可以独立转动，能够精准定位声音来源。它们能够感知的高频声音高达64kHz，优于人类。\\n   - **嗅觉**：猫的嗅觉比人类敏锐约14倍，鼻腔内有大约2亿个嗅觉受器，是捕猎的关键能力。\\n   - **味觉**：猫的味觉比较有限，失去了对甜味的感知，但是对酸、苦和咸味仍然敏感。\\n\\n2. **爪子**：猫的爪子非常尖锐，并且具有伸缩功能，能够安静地行走。它们的趾底有脂肪垫，走路时不发出声音。\\n\\n3. **身体构造**：猫灵活的身体结构使它们能够轻松地跳跃和攀爬。它们的感官毛（触须）可以感知非常微弱的空气波动，帮助它们判断周围环境。\\n\\n4. **行为习性**：猫有磨爪的习惯，常用爪子磨擦物体以维持爪子的健康。此外，猫会用气味标记地盘，通过脸部和身体上的腺体分泌的特殊费洛蒙进行社交互动。\\n\\n这些特征使得猫在自然界中成为有效的捕猎者和适应环境的生物。'}\n"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T07:01:17.383282Z",
     "start_time": "2025-09-11T07:01:08.567944Z"
    }
   },
   "cell_type": "code",
   "source": "print(agent_executor.invoke({\"input\": \"今天上海天气怎么样\"}))",
   "id": "71eb8a9d34180894",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m\n",
      "Invoking: `tavily_search_results_json` with `{'query': '上海天气'}`\n",
      "\n",
      "\n",
      "\u001B[0m\u001B[36;1m\u001B[1;3m[{'title': '上海-天气预报', 'url': 'https://www.nmc.cn/publish/forecast/ASH/shanghai.html', 'content': '土壤水分监测\\n       农业干旱综合监测\\n       关键农时农事\\n       农业气象周报\\n       农业气象月报\\n       生态气象监测评估\\n       农业气象专报\\n       作物发育期监测\\n       农业气象灾害风险预警\\n       国外农业气象月报\\n\\n   数值预报\\n\\n       CMA全球天气模式\\n       CMA全球集合模式\\n       CMA区域模式\\n       CMA区域集合模式\\n       CMA台风模式\\n       海浪模式\\n\\n1.    当前位置：首页\\n2.   上海市\\n3.   上海天气预报\\n\\n省份：城市：\\n\\n17:15更新\\n\\nImage 4\\n\\n日出05:35\\n\\n 上海 \\n\\n28.8℃\\n\\n日落18:09\\n\\n 降水量 \\n\\n0mm\\n\\n西南风\\n\\n微风\\n\\n 相对湿度 \\n\\n72%\\n\\n 体感温度 \\n\\n33.3℃\\n\\n空气质量：优\\n\\n舒适度：暖，不舒适\\n\\n 雷达图 \\n\\nImage 5\\n\\n24小时预报7天预报10天预报11-30天预报\\n\\n 发布时间：09-08 20:00 \\n\\n 09/08 \\n\\n周一 \\n\\n 27℃', 'score': 0.755078}]\u001B[0m\u001B[32;1m\u001B[1;3m今天上海的天气为28.8℃，微风（西南风），相对湿度72%。体感温度约为33.3℃，没有降水，空气质量良好。总体上天气较为舒适，但由于体感温度较高，可能会感觉不够舒适。\n",
      "\n",
      "详细天气预报可以查看 [这里](https://www.nmc.cn/publish/forecast/ASH/shanghai.html)。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '今天上海天气怎么样', 'output': '今天上海的天气为28.8℃，微风（西南风），相对湿度72%。体感温度约为33.3℃，没有降水，空气质量良好。总体上天气较为舒适，但由于体感温度较高，可能会感觉不够舒适。\\n\\n详细天气预报可以查看 [这里](https://www.nmc.cn/publish/forecast/ASH/shanghai.html)。'}\n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 7 添加记忆",
   "id": "67aa014df60651f4"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T07:03:12.789042Z",
     "start_time": "2025-09-11T07:03:11.240914Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_community.chat_message_histories import ChatMessageHistory\n",
    "\n",
    "from langchain_core.chat_history import BaseChatMessageHistory\n",
    "\n",
    "from langchain_core.runnables.history import RunnableWithMessageHistory\n",
    "\n",
    "store = {}\n",
    "\n",
    "# 调取指定session_id对应的memory\n",
    "def get_session_history(session_id: str) -> BaseChatMessageHistory:\n",
    "\n",
    "    if session_id not in store:\n",
    "        store[session_id] = ChatMessageHistory()\n",
    "\n",
    "    return store[session_id]\n",
    "\n",
    "agent_with_chat_history = RunnableWithMessageHistory(\n",
    "    runnable=agent_executor,\n",
    "    get_session_history=get_session_history,\n",
    "    input_messages_key=\"input\",\n",
    "    history_messages_key=\"chat_history\",\n",
    ")\n",
    "\n",
    "response = agent_with_chat_history.invoke(\n",
    "    {\"input\": \"Hi，我的名字是Cyber\"},\n",
    "    config={\"configurable\": {\"session_id\": \"123\"}},\n",
    ")\n",
    "\n",
    "print(response)"
   ],
   "id": "dee6d438c8d7eef3",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m你好，Cyber！很高兴见到你。有什么我可以帮助你的吗？\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': 'Hi，我的名字是Cyber', 'chat_history': [], 'output': '你好，Cyber！很高兴见到你。有什么我可以帮助你的吗？'}\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T07:03:38.734882Z",
     "start_time": "2025-09-11T07:03:37.336700Z"
    }
   },
   "cell_type": "code",
   "source": [
    "response = agent_with_chat_history.invoke(\n",
    "    {\"input\": \"我叫什么名字?\"},\n",
    "    config={\"configurable\": {\"session_id\": \"123\"}},\n",
    ")\n",
    "\n",
    "print(response)"
   ],
   "id": "3d76881393ef4315",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m你叫Cyber。有什么特别的事情想和我分享吗？\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '我叫什么名字?', 'chat_history': [HumanMessage(content='Hi，我的名字是Cyber', additional_kwargs={}, response_metadata={}), AIMessage(content='你好，Cyber！很高兴见到你。有什么我可以帮助你的吗？', additional_kwargs={}, response_metadata={})], 'output': '你叫Cyber。有什么特别的事情想和我分享吗？'}\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-11T07:04:01.685043Z",
     "start_time": "2025-09-11T07:04:00.280455Z"
    }
   },
   "cell_type": "code",
   "source": [
    "response = agent_with_chat_history.invoke(\n",
    "    {\"input\": \"我叫什么名字?\"},\n",
    "    config={\"configurable\": {\"session_id\": \"4566\"}},\n",
    ")\n",
    "print(response)"
   ],
   "id": "e0046cfeba0c75f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m抱歉，我无法得知您的名字。如果您愿意，可以告诉我您的名字！\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '我叫什么名字?', 'chat_history': [], 'output': '抱歉，我无法得知您的名字。如果您愿意，可以告诉我您的名字！'}\n"
     ]
    }
   ],
   "execution_count": 13
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
